home *** CD-ROM | disk | FTP | other *** search
/ Australian Personal Computer 2000 July / CD 3 / redhat-6.2.iso / RedHat / instimage / usr / lib / anaconda / iw / package.py < prev    next >
Encoding:
Python Source  |  2000-03-08  |  17.2 KB  |  464 lines

  1. from gtk import *
  2. from gnome.ui import *
  3. from iw import *
  4. from string import *
  5. from thread import *
  6. from examine import *
  7. import rpm
  8. import GdkImlib
  9. import string
  10. import sys
  11. import xpms
  12. from translate import _
  13.  
  14. class IndividualPackageSelectionWindow (InstallWindow):
  15.  
  16.     def __init__ (self, ics):
  17.     InstallWindow.__init__ (self, ics)
  18.  
  19.         self.todo = ics.getToDo ()
  20.         ics.setTitle (_("Individual Package Selection"))
  21.         ics.setNextEnabled (1)
  22.         ics.readHTML ("sel-indiv")
  23.         ics.setHelpEnabled (FALSE)
  24.         self.DIR = 0
  25.         self.DIR_UP = 1
  26.         self.RPM = 2
  27.  
  28.         self.updatingIcons = FALSE
  29.  
  30.     self.idirImage = GdkImlib.create_image_from_xpm (xpms.I_DIRECTORY_XPM)
  31.     self.idirUpImage = GdkImlib.create_image_from_xpm (xpms.I_DIRECTORY_UP_XPM)
  32.     self.packageImage = GdkImlib.create_image_from_xpm (xpms.PACKAGE_XPM)
  33.     self.packageSelectedImage = GdkImlib.create_image_from_xpm (xpms.PACKAGE_SELECTED_XPM)
  34.  
  35.     def getPrev (self):
  36.         for x in self.ics.getICW ().stateList:
  37.             if isinstance (x, PackageSelectionWindow):
  38.                 return PackageSelectionWindow
  39.             elif isinstance (x, UpgradeExamineWindow):
  40.                 return UpgradeExamineWindow
  41.         return None
  42.     
  43.  
  44.     def build_tree (self, x):
  45.         if (x == ()): return ()
  46.         if (len (x) == 1): return (x[0],)
  47.         else: return (x[0], self.build_tree (x[1:]))
  48.  
  49.     def merge (self, a, b):
  50.         if a == (): return self.build_tree (b)
  51.         if b == (): return a
  52.         if b[0] == a[0]:
  53.             if len (a) > 1 and isinstance (a[1], type (())):
  54.                 return (a[0],) + (self.merge (a[1], b[1:]),) + a[2:]
  55.             elif b[1:] == (): return a
  56.             else: return (a[0],) + (self.build_tree (b[1:]),) + a[1:]
  57.         else:
  58.             return (a[0],) + self.merge (a[1:], b)
  59.  
  60.     def build_ctree (self, list, cur_parent = None, prev_node = None, path = ""):
  61.         if (list == ()): return
  62.         
  63.         if (len (list) > 1 and isinstance (list[1], type (()))): leaf = FALSE
  64.         else: leaf = TRUE
  65.     
  66.         if isinstance (list[0], type (())):
  67.             self.build_ctree (list[0], prev_node, None, self.ctree.node_get_row_data (prev_node))
  68.             self.build_ctree (list[1:], cur_parent, None, path)
  69.         else:
  70.             node = self.ctree.insert_node (cur_parent, None, (list[0],), 2,
  71.                                            self.closed_p, self.closed_b, self.open_p, self.open_b, leaf)
  72.             cur_path = path + "/" + list[0]
  73.             self.ctree.node_set_row_data (node, cur_path)
  74.             self.build_ctree (list[1:], cur_parent, node, path)
  75.  
  76.     def draw_root_icons (self):
  77.         self.iconList.freeze ()
  78.         self.iconList.clear ()
  79.         for x in self.ctree.base_nodes ():
  80.             dirName = self.ctree.get_node_info (x)[0]
  81.             pos = self.iconList.append_imlib (self.idirImage, dirName)
  82.             self.iconList.set_icon_data (pos, (self.DIR, x))
  83.         self.iconList.thaw ()
  84.  
  85.  
  86.     def get_rpm_desc (self, header):
  87.         desc = replace (header[rpm.RPMTAG_DESCRIPTION], "\n\n", "\x00")
  88.         desc = replace (desc, "\n", " ")
  89.         desc = replace (desc, "\x00", "\n\n")
  90.         return desc
  91.  
  92.     def clear_package_desc (self):
  93.         self.currentPackage = None
  94.         self.packageName.set_text ("")
  95.         self.packageSize.set_text ("")                 
  96.         self.packageDesc.freeze ()
  97.         self.packageDesc.delete_text (0, -1)
  98.         self.packageDesc.thaw ()
  99.         self.cbutton.set_active (FALSE)
  100.         self.cbutton.set_sensitive (FALSE)
  101.  
  102.     
  103.     def select_icon (self, iconList, arg1, event, *args):
  104.         if event and event.type != GDK._2BUTTON_PRESS and event.type != GDK.BUTTON_PRESS:
  105.             return
  106.         icon_data = iconList.get_icon_data (arg1)
  107.         if not icon_data: return
  108.  
  109.         if event and iconList.icon_is_visible (arg1) != VISIBILITY_FULL:
  110.             allocation = iconList.get_allocation ()
  111.             if (event.y - self.iconListAdj.value) < (allocation[3]/2):
  112.                 self.iconList.moveto (arg1, 0.0)
  113.             else:
  114.                 self.iconList.moveto (arg1, 1.0)
  115.  
  116.         if event == None or event.type == GDK.BUTTON_PRESS:
  117.             if icon_data[0] == self.RPM:
  118.                 header = icon_data[1]
  119.                 # if we're already displaying the current package, don't redraw
  120.                 if self.packageName.get () == "%s-%s-%s" % (header[rpm.RPMTAG_NAME],
  121.                                                             header[rpm.RPMTAG_VERSION],
  122.                                                             header[rpm.RPMTAG_RELEASE]):
  123.                     return
  124.                 
  125.                 self.currentPackage = header
  126.                 self.currentPackagePos = arg1
  127.                 self.cbutton.set_sensitive (TRUE)
  128.                 if header.selected:
  129.                     self.cbutton.set_active (TRUE)
  130.                 else:
  131.                     self.cbutton.set_active (FALSE)
  132.                     
  133.                 self.packageName.set_text ("%s-%s-%s" % (header[rpm.RPMTAG_NAME],
  134.                                                          header[rpm.RPMTAG_VERSION],
  135.                                                          header[rpm.RPMTAG_RELEASE]))
  136.                 self.packageSize.set_text ("%.1f KBytes" % (header[rpm.RPMTAG_SIZE] / 1024.0))
  137.                 self.packageDesc.freeze ()
  138.                 self.packageDesc.delete_text (0, -1)
  139.                 self.packageDesc.insert_defaults (self.get_rpm_desc (header))
  140.                 self.packageDesc.thaw ()
  141.             else:
  142.                 self.clear_package_desc ()
  143.             return
  144.  
  145.         if icon_data[0] == self.RPM:
  146.             active = self.cbutton.get_active ()
  147.             if active == TRUE:
  148.                 self.cbutton.set_active (FALSE)
  149.             else:
  150.                 self.cbutton.set_active (TRUE)
  151.  
  152.         if icon_data[0] == self.DIR_UP:
  153.             current_node = icon_data[1].parent
  154.             if current_node:
  155.                 self.ctree.select (current_node)
  156.             else:
  157.                 # handle the imaginary root node
  158.                 current_node = self.ctree.base_nodes ()[0]
  159.                 self.ctree.unselect (icon_data[1])
  160.                 self.draw_root_icons ()
  161.                 
  162.         elif icon_data[0] == self.DIR:
  163.             current_node = icon_data[1]
  164.             self.ctree.select (current_node)
  165.             if (current_node.parent):
  166.                 self.ctree.expand_to_depth (current_node.parent, 1)
  167.     else: return
  168.  
  169.         if self.ctree.node_is_visible (current_node) != VISIBILITY_FULL:
  170.             self.ctree.node_moveto (current_node, 0, 0.5, 0.0)
  171.  
  172.     def select (self, ctree, node, *args):
  173.         self.clear_package_desc ()
  174.         self.iconList.freeze ()
  175.         self.iconList.clear ()
  176.         self.iconList.append_imlib (self.idirUpImage, _("Up"))
  177.         self.iconList.set_icon_data (0, (self.DIR_UP, node))
  178.         for x in node.children:
  179.             dirName = ctree.get_node_info (x)[0]
  180.             pos = self.iconList.append_imlib (self.idirImage, dirName)
  181.             self.iconList.set_icon_data (pos, (self.DIR, x))
  182.  
  183.         try:
  184.             # this code is wrapped in a generic exception handler since we dont
  185.             # care if we access a namespace that lacks rpms
  186.             
  187.             # drop the leading slash off the package namespace
  188.             for header in self.flat_groups[ctree.node_get_row_data (node)[1:]]:
  189.                 if header.selected:
  190.                     packageIcon = self.packageSelectedImage
  191.                     self.cbutton.set_active (TRUE)
  192.                 else:
  193.                     packageIcon = self.packageImage
  194.                     self.cbutton.set_active (FALSE)
  195.                 
  196.                 pos = self.iconList.append_imlib (packageIcon, header[rpm.RPMTAG_NAME])
  197.                 self.iconList.set_icon_data (pos, (self.RPM, header))
  198.         except:
  199.             pass
  200.  
  201.     # make sure that the iconList is reset to show the initial files in a dir,
  202.         # unless we re rebuilding the icons because one has been selected for install
  203.         if not self.updatingIcons:
  204.             self.iconListSW.get_vadjustment ().set_value (0.0)
  205.         self.iconList.thaw ()
  206.         self.iconList.show_all ()
  207.  
  208.  
  209.     def installButtonToggled (self, cbutton, *args):
  210.         if not self.currentPackage: return
  211.         oldSelectedStatus = self.currentPackage.selected
  212.         
  213.         if cbutton.get_active ():
  214.             self.currentPackage.selected = 1
  215.         else:
  216.             self.currentPackage.selected = 0
  217.  
  218.         
  219.         if oldSelectedStatus != self.currentPackage.selected:
  220.             self.updatingIcons = TRUE
  221.             self.ctree.select (self.ctree.selection[0])
  222.             self.iconList.select_icon (self.currentPackagePos)
  223.             self.updatingIcons = FALSE
  224.             
  225. #            self.iconList.freeze ()
  226. #            if self.currentPackage.selected:
  227. #                packageIcon = "/home/devel/pnfisher/gnome-package-checked.png"
  228. #            else:
  229. #                packageIcon = "/usr/src/gnorpm/gnome-package.xpm"
  230.  
  231. #            print self.currentPackagePos
  232. #            self.iconList.remove (self.currentPackagePos)
  233. #            print _("got here")
  234. #            self.iconList.insert (self.currentPackagePos, packageIcon,
  235. #                                  self.currentPackage[rpm.RPMTAG_NAME])
  236. #            self.iconList.set_icon_data (self.currentPackagePos, (self.RPM, self.currentPackage))
  237.             
  238. #            self.iconList.thaw ()
  239.  
  240.  
  241.     def getScreen (self):
  242.         threads_leave ()
  243.         self.todo.getHeaderList()
  244.         threads_enter ()
  245.  
  246.         self.path_mapping = {}
  247.         self.ctree = GtkCTree ()
  248.         self.ctree.set_selection_mode (SELECTION_BROWSE)
  249.         # Kludge to get around CTree s extremely broken focus behavior
  250.         self.ctree.unset_flags (CAN_FOCUS)
  251.  
  252.         if (not self.__dict__.has_key ("open_p")):
  253.             self.open_p, self.open_b = create_pixmap_from_xpm_d (self.ctree,
  254.                                                                  None, xpms.DIRECTORY_OPEN_XPM)
  255.             self.closed_p, self.closed_b = create_pixmap_from_xpm_d (self.ctree,
  256.                                                                      None, xpms.DIRECTORY_CLOSE_XPM)
  257.  
  258.         groups = {}
  259.  
  260.         # go through all the headers and grok out the group names, placing
  261.         # packages in lists in the groups dictionary.
  262.         
  263.         for key in self.todo.hdList.packages.keys():
  264.             header = self.todo.hdList.packages[key]
  265.             if not groups.has_key (header[rpm.RPMTAG_GROUP]):
  266.                 groups[header[rpm.RPMTAG_GROUP]] = []
  267.             # don't display package if it is in the Base group
  268.             if not self.todo.comps["Base"].items.has_key (header):
  269.                 groups[header[rpm.RPMTAG_GROUP]].append (header)
  270.  
  271.         keys = groups.keys ()
  272.         keys.sort ()
  273.         self.flat_groups = groups
  274.         index = 0
  275.  
  276.         # now insert the groups into the list, then each group's packages
  277.         # after sorting the list
  278.         def cmpHdrName(first, second):
  279.             if first[rpm.RPMTAG_NAME] < second[rpm.RPMTAG_NAME]:
  280.                 return -1
  281.             elif first[rpm.RPMTAG_NAME] == second[rpm.RPMTAG_NAME]:
  282.                 return 0
  283.             return 1
  284.  
  285.         groups = ()
  286.         for key in keys:
  287.             self.flat_groups[key].sort (cmpHdrName)
  288.             groups = self.merge (groups, split (key, "/"))
  289.         self.ctree.freeze ()
  290.         self.build_ctree (groups)
  291.  
  292.         for base_node in self.ctree.base_nodes ():
  293.             self.ctree.expand_recursive (base_node)
  294.         self.ctree.columns_autosize ()
  295.         for base_node in self.ctree.base_nodes ():
  296.             self.ctree.collapse_recursive (base_node)
  297.         self.ctree.thaw ()
  298.  
  299.         self.ctree.connect ("tree_select_row", self.select)
  300.         sw = GtkScrolledWindow ()
  301.         sw.set_border_width (5)
  302.         sw.set_policy (POLICY_NEVER, POLICY_AUTOMATIC)
  303.         sw.add (self.ctree)
  304.         iconHBox = GtkHBox ()
  305.         iconHBox.pack_start (sw, FALSE)
  306.  
  307.         self.iconList = GnomeIconList (90)
  308.         self.iconList.set_selection_mode (SELECTION_MULTIPLE)
  309.     self.iconList.connect ("select_icon", self.select_icon)
  310.         self.draw_root_icons ()
  311.  
  312.         self.iconListSW = GtkScrolledWindow ()
  313.         self.iconListSW.set_border_width (5)
  314.         self.iconListSW.set_policy (POLICY_NEVER, POLICY_AUTOMATIC)
  315.         self.iconListSW.add (self.iconList)
  316.         self.iconListAdj = self.iconListSW.get_vadjustment ()
  317.         iconHBox.pack_start (self.iconListSW)
  318.  
  319.         descVBox = GtkVBox ()        
  320.         descVBox.pack_start (GtkHSeparator (), FALSE, padding=3)
  321.  
  322.  
  323.         hbox = GtkHBox ()
  324.         label = GtkLabel (_("Name: "))
  325.         self.packageName = GtkLabel ()
  326.         self.packageName.set_alignment (0.0, 0.0)
  327.         hbox.pack_start (label, FALSE, padding=5)
  328.         hbox.pack_start (self.packageName, FALSE)
  329.         label = GtkLabel (_("Package Details"))
  330.         label.set_alignment (1.0, 1.0)
  331.         hbox.pack_start (label, padding=5)
  332.         descVBox.pack_start (hbox, FALSE)
  333.  
  334.         hbox = GtkHBox ()
  335.         label = GtkLabel (_("Size: "))
  336.         self.packageSize = GtkLabel ()
  337.         self.packageSize.set_alignment (0.0, 0.5)
  338.         hbox.pack_start (label, FALSE, padding=5)
  339.         hbox.pack_start (self.packageSize, FALSE)
  340.         align = GtkAlignment (1.0, 0.0)
  341.         self.cbutton = GtkCheckButton (_("Select Package For Installation"))
  342.         self.cbutton.set_sensitive (FALSE)
  343.         self.cbutton.connect ("toggled", self.installButtonToggled)
  344.         self.cbutton.children()[0].set_alignment (1.0, 0.5)
  345.         align.add (self.cbutton)
  346.         hbox.pack_start (align, padding=5)
  347.         descVBox.pack_start (hbox, FALSE)
  348.  
  349.         descSW = GtkScrolledWindow ()
  350.         descSW.set_border_width (5)
  351.         descSW.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC)
  352.  
  353.         self.packageDesc = GtkText ()
  354.         self.packageDesc.set_word_wrap (TRUE)
  355.         self.packageDesc.set_line_wrap (TRUE)
  356.         self.packageDesc.set_editable (FALSE)
  357.         descSW.add (self.packageDesc)
  358.         descSW.set_usize (-1, 100)
  359.  
  360.         descVBox.pack_start (descSW)
  361.  
  362. #        descFrame = GtkFrame (_("Package Details"))
  363. #        descFrame.set_border_width (5)
  364. #        descFrame.add (descVBox)
  365.         
  366.         vbox = GtkVBox ()
  367.         vbox.pack_start (iconHBox)
  368.         vbox.pack_start (descVBox, FALSE)
  369.  
  370.         return vbox
  371.  
  372. class PackageSelectionWindow (InstallWindow):
  373.     def __init__ (self, ics):
  374.     InstallWindow.__init__ (self, ics)
  375.  
  376.         ics.setTitle (_("Package Group Selection"))
  377.         ics.setNextEnabled (1)
  378.         ics.readHTML ("sel-group")
  379.         self.selectIndividualPackages = FALSE
  380.  
  381.     def getNext (self):
  382.     if not self.__dict__.has_key ("individualPackages"):
  383.         return None
  384.  
  385.         # turn off all the comps
  386.         for comp in self.todo.comps:
  387.             if not comp.hidden:
  388.                 comp.unselect(0)
  389.  
  390.         # turn on each package group in order (msw's code requires this)
  391.         for (button, comp) in self.checkButtons:
  392.             if button.get_active ():
  393.                 comp.select (1)
  394.  
  395.         del self.checkButtons
  396.  
  397.         gotoIndividualPackages = self.individualPackages.get_active ()
  398.         del self.individualPackages
  399.         
  400.         if gotoIndividualPackages:
  401.             self.selectIndividualPackages = TRUE
  402.             return IndividualPackageSelectionWindow
  403.         else:
  404.             self.selectIndividualPackages = FALSE
  405.           
  406.         return None
  407.  
  408.     def getScreen (self):
  409.         threads_leave ()
  410.         self.todo.getHeaderList ()
  411.         self.todo.getCompsList()
  412.         threads_enter ()
  413.  
  414.         sw = GtkScrolledWindow ()
  415.         sw.set_border_width (5)
  416.         sw.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC)
  417.  
  418.         box = GtkVBox (FALSE, 0)
  419.  
  420.     self.checkButtons = []        
  421.         for comp in self.todo.comps:
  422.             if not comp.hidden:
  423.                 pixname = string.replace (comp.name, ' ', '-')
  424.                 pixname = string.replace (pixname, '/', '-')
  425.                 pixname = string.replace (pixname, '.', '-')
  426.                 pixname = string.replace (pixname, '(', '-')
  427.                 pixname = string.replace (pixname, ')', '-')
  428.                 pixname = string.lower (pixname) + ".png"
  429.                 picture = None
  430.                 checkButton = None
  431.                 im = self.ics.readPixmap (pixname)
  432.                 if im:
  433.                     im.render ()
  434.                     pix = im.make_pixmap ()
  435.                     hbox = GtkHBox (FALSE, 5)
  436.                     hbox.pack_start (pix, FALSE, FALSE, 0)
  437.                     label = GtkLabel (comp.name)
  438.                     label.set_alignment (0.0, 0.5)
  439.                     hbox.pack_start (label, TRUE, TRUE, 0)
  440.                     checkButton = GtkCheckButton ()
  441.                     checkButton.add (hbox)
  442.                 else:
  443.                     checkButton = GtkCheckButton (comp.name)
  444.  
  445.                 checkButton.set_active (comp.selected)
  446.                 self.checkButtons.append ((checkButton, comp))
  447.                 box.pack_start (checkButton)
  448.  
  449.         sw.add_with_viewport (box)
  450.         box.set_focus_hadjustment(sw.get_hadjustment ())
  451.         box.set_focus_vadjustment(sw.get_vadjustment ())
  452.  
  453.         vbox = GtkVBox (FALSE, 5)
  454.         self.individualPackages = GtkCheckButton (_("Select individual packages"))
  455.         self.individualPackages.set_active (self.selectIndividualPackages)
  456.         align = GtkAlignment (0.5, 0.5)
  457.         align.add (self.individualPackages)
  458.  
  459.         vbox.pack_start (sw, TRUE)
  460.         vbox.pack_start (align, FALSE)
  461.         
  462.         return vbox
  463.  
  464.